//导出方法
// 1.直接导出 用 export导出声明的变量,直接导出的需要使用解构赋值{} 不能直接引文件名  
// export const xx = ({})=>{}
// 2.模块导出如下module.exports = {}
let timeoutFdJl = null;
module.exports = {
	/**
	 * @description 提示信息 uni.showToast(OBJECT)
	 * @param {string} title 提示标题 7个字
	 * @param {number} duration 提示时间
	 * @param {boolean} mask 遮罩层
	 * @param {string} icon 图标层
	 */
	msg: function(title, duration = 1500, mask = false, icon = 'none') {
		//统一提示方便全局修改
		if (Boolean(title) === false) {
			return;
		}
		uni.showToast({
			title,
			duration,
			mask,
			icon
		});
	},
	/**
	 * @description 提示选择信息 uni.showModal(OBJECT)
	 * @param {string} title 提示标题
	 * @param {string} content 提示内容
	 * @param {string} icon 图标层
	 * @return {fn} success 成功回调
	 */
	showModal: function(title, content, confirm) {
		if (!title) {
			title = '温馨提示';
		}
		//统一提示方便全局修改
		uni.showModal({
			title,
			content,
			success: res => {
				if (res.confirm) {
					// console.log('用户点击确定');
					confirm(true)
				} else if (res.cancel) {
					// console.log('用户点击取消');
					confirm(false)
				}
			}
		});
	},
	/**
	 * @description 图片加载失败默认图
	 * @param {string} data 对象
	 * @param {string} key 键名
	 * @param {string} isObj 是否键值图片
	 * @return {*}
	 * 特别说明，如果是对象，data为对象，key为键值，如果是数组，则data是数组。key是下表 
	 */
	imgError: function(data, key, isObj = true) {
		if (isObj) {
			return data[key] = '../../static/errorImg.png';
		} else {
			return data.splice(key, 1, '../../static/errorImg.png');
		}
	},
	doneTime(form,key){
		if (form[key] && form[key].length == 2) {
			let inputtime = []
			inputtime[0] = this.$u.timeFormat(form[key][0], 'yyyy-mm-dd')
			inputtime[1] = this.$u.timeFormat(form[key][1], 'yyyy-mm-dd')
			// query.meetingtime = inputtime
			return inputtime
		} else if (form[key] && form[key].length == 1) {
			let inputtime = ''
			inputtime = form[key][0]
			// query.meetingtime = inputtime
			return inputtime
		}
	},
	/**
	 * @description 页面跳转
	 * @param {string} url 需要跳转的应用内非 tabBar 的页面的路径
	 * @param {boolean} needLogin 是否需要登陆
	 * 
	 */
	//不能在 App.vue 里面进行页面跳转。
	to: function(url, type, needLogin = false) {
		if (!url || url.length == 0) {
			return false
		}
		if (!type) {
			type = 'navigateTo';
		}
		if (needLogin && !uni.getStorageSync('token')) {
			uni.navigateTo({
				url: '/pages/login/login'
			})
			return;
		}

		switch (type) {
			case "navigateTo": //保留当前页面，跳转到应用内的某个页面，可带参数
				uni.navigateTo({
					url
				})
				break;
			case "redirectTo": //关闭当前页面，跳转到应用内的某个页面，可带参数
				uni.redirectTo({
					url
				})
				break;
			case "reLaunch": //关闭所有页面，打开到应用内的某个页面，可带参数，如果是trabbar则不能带参数
				uni.reLaunch({
					url
				})
				break;
			case "switchTab": //跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面，路径后不能带参数
				uni.switchTab({
					url
				})
				break;
		}
	},
	/**
	 * @description 返回页面
	 * @param {Object} num 返回页面数量
	 */
	back: function(num = 1, delay = 0) {
		setTimeout(() => {
			uni.navigateBack({
				delta: num
			});
			// #ifdef H5
			//H5页面刷新找不到上一个页面，需要下面方法进行处理
			// history.back()
			// #endif
		}, delay)
	},
	/**
	 * @description 打电话 Android需要在 manifest.json 增加权限 <uses-permission android:name="android.permission.CALL_PHONE"/>
	 * @param {string} phone 电话
	 */
	makePhone: function(phoneNumber) {
		uni.makePhoneCall({
			phoneNumber //仅为示例
		});
	},
	/**
	 * @description 设置系统剪贴板的内容。
	 * @param {string} data 需要设置的内容
	 * @param {boolean} showToast 配置是否弹出提示，默认弹出提示 App (3.2.13+)、H5 (3.2.13+)
	 * @return {fn} 复制成功回调
	 */
	copyText: function(data, success, showToast) {
		uni.setClipboardData({
			data, //仅为示例
			showToast,
			success: () => {
				if (success) {
					success()
				}
			}
		});
	},
	/**
	 * @description 输入一个值，返回其数据类型**
	 * @param {*} para 需要设置的内容
	 * @return {*} 数据类型
	 */
	isType(para) {
		return Object.prototype.toString.call(para)
	},
	/**
	 * @description 转换字符串，undefined,null等转化为""
	 * @param {string} data 转换字符串
	 * @reurn {string} 如果没有值或者undefined,null等转化为""，否则返回str
	 */
	praseStrEmpty: function(str) {
		return !str || str === 'undefined' || str === 'null' ? '' : str
	},
	/**
	 * @description 价格两位小数
	 * @param {string} price 转换字符串
	 * @reurn {*} 价格
	 */
	priceFixed: function(price) {
		if (price) {
			return Number(price).toFixed(2)
		} else {
			price = 0
			return price.toFixed(2)
		}
		console.log(price);

	},
	/**
	 * @description 价格两位小数
	 * @param {string} str ：字符串
	 * @param {number} frontLen ：前面保留位数
	 * @param {number} endLen ：后面保留位数
	 * @reurn {*} 张*，李*四，183****1234,131************12
	 */
	hidePhone: function(str, frontLen, endLen) {
		if (str) {
			var len = str.length - frontLen - endLen;
			var strat = '';
			for (var i = 0; i < len; i++) {
				strat += '*';
			}
			return str.substr(0, frontLen) + strat + str.substr(str.length - endLen);
		}
	},
	/* 处理富文本中的图片 */
	richImg: function(richtext) {
		if (!richtext) {
			return;
		}
		const regex = new RegExp('<img', 'gi');
		return richtext.replace(/(\<img|\<p)/gi, function($0, $1) {
			return {
				"<img": '<img style="max-width:100%;height:auto;"',
				"<p": '<p ',
				"<article": "<div",
				"</article": "</div",
				"<header": "<div",
				"</header": "</div"
			} [$1];
		});
	},
	/** 
	 * @description 2数之间的随机数，包含,随机数为最小值到最大值之间的
	 * @param {number} min 最小值 
	 * @param {number} max 最大值 
	 * @reurn {number} 返回随机数 
	 */
	random: function(min, max) {
		switch (arguments.length) {
			case 1:
				return parseInt(Math.random() * min + 1, 10);
				break;
			case 2:
				return parseInt(Math.random() * (max - min + 1) + min, 10);
				break;
			default:
				return 0;
		}
	},
	getDistance: function(lat1, lng1, lat2, lng2) {
		var radLat1 = lat1 * Math.PI / 180.0;
		var radLat2 = lat2 * Math.PI / 180.0;
		var a = radLat1 - radLat2;
		var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
		var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
			Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
		s = s * 6378.137; // EARTH_RADIUS;
		s = Math.round(s * 10000) / 10000;
		return s;
	},
	/** 
	 * @description 日期时间
	 * @param {string} type number, str, array
	 * @param {string} addTime 修正数值，单位 : 毫秒 
	 * @reurn {number||str||array} number(时间戳),str（YY-mm-dd HH:ii:ss）,array
	 */
	now: function(type, addTime) {
		let dateObj = new Date();
		let cTime = dateObj.getTime();
		if (addTime) {
			cTime += addTime;
		}
		if (!type) {
			type = 'number';
		}
		if (type == 'number') {
			return cTime;
		} else if (type == 'str') {
			return this.toDate(cTime / 1000, 'str');
		} else if (type == 'array') {
			return this.toDate(cTime / 1000, 'array');
		}
	},
	/**
	 * @description 获取周几
	 * @param {string} date 日期 YY-mm-dd ，给定日期返回传入日期时周几
	 * @return {string} 周几 
	 */
	getWeek: function(date) {
		let now = date ? new Date(date) : new Date();
		let day = now.getDay();
		let weeks = new Array(
			"周日",
			"周一",
			"周二",
			"周三",
			"周四",
			"周五",
			"周六"
		);
		let week = weeks[day];
		return week;
	},
	/**  
	 * @description 时间戳转 YY-mm-dd HH:ii:ss
	 * @param {string} timeStamp 时间戳( 自动识别毫秒或秒形式)
	 * @param {string} returnType 返回值类型 str|| array
	 * @return {str||array} ( str - 字符串形式 , array -  数值形式便于自己转换其他形式 )
	 */
	toDate: function(timeStamp, returnType) {
		timeStamp = parseInt(timeStamp);
		let date = new Date();
		if (timeStamp < 90000000000) {
			date.setTime(timeStamp * 1000);
		} else {
			date.setTime(timeStamp);
		}
		let y = date.getFullYear();
		let m = date.getMonth() + 1;
		m = m < 10 ? ('0' + m) : m;
		let d = date.getDate();
		d = d < 10 ? ('0' + d) : d;
		let h = date.getHours();
		h = h < 10 ? ('0' + h) : h;
		let minute = date.getMinutes();
		let second = date.getSeconds();
		minute = minute < 10 ? ('0' + minute) : minute;
		second = second < 10 ? ('0' + second) : second;
		if (returnType == 'str') {
			return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
		}
		return [y, m, d, h, minute, second];
	},
	/**  
	 * @description 字符串转时间戳
	 * @param {string} timeStamp 字符串形式的时间，支持格式 : YYYY-MM-DD HH:ii:ss 或 MM/DD/YYYY HH:ii:ss
	 * @return {number} 返回值时间戳
	 */
	toTimeStamp: function(timeStamp) {
		var reg = /^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
		var res = timeStamp.match(reg);
		if (res == null) {
			var reg2 = /^([0-9]{2})\/([0-9]{2})\/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
			var res2 = timeStamp.match(reg2);
			if (res2 == null) {
				console.log('时间格式错误 E001');
				return false;
			}
			var year = parseInt(res2[3]);
			var month = parseInt(res2[1]);
			var day = parseInt(res2[2]);
			var h = parseInt(res2[4]);
			var i = parseInt(res2[5]);
			var s = parseInt(res2[6]);
		} else {
			var year = parseInt(res[1]);
			var month = parseInt(res[2]);
			var day = parseInt(res[3]);
			var h = parseInt(res[4]);
			var i = parseInt(res[5]);
			var s = parseInt(res[6]);
		}
		if (year < 1000) {
			console.log('时间格式错误');
			return false;
		}
		if (h < 0 || h > 24) {
			console.log('时间格式错误');
			return false;
		}
		if (i < 0 || i > 60) {
			console.log('时间格式错误');
			return false;
		}
		if (s < 0 || s > 60) {
			console.log('时间格式错误');
			return false;
		}
		return Date.parse(new Date(year, month - 1, day, h, i, s));
	},
	/**  
	 * @description 根据时间戳计算多少分钟/小时/天之前
	 * @param {string} time 时间戳 13位或10位
	 * @return {str} 返回值
	 */
	fromTime: function(time) {
		if (time < 90000000000) {
			time *= 1000;
		}
		let timer = new Date().getTime() - time;
		timer = parseInt(timer / 1000);
		if (timer < 180) {
			return '刚刚';
		} else if (timer >= 180 && timer < 3600) {
			return parseInt(timer / 60) + '分钟前';
		} else if (timer >= 3600 && timer < 86400) {
			return parseInt(timer / 3600) + '小时前';
		} else if (timer >= 86400 && timer < 2592000) {
			return parseInt(timer / 86400) + '天前';
		} else {
			return this.toDate(time, 'str');
		}
	},
	/**
	 * @description: 指定日期前/后几天
	 * @param {*} date 指定日期
	 * @param {number} day 距离当前几天
	 * @return {string}
	 */
	getNextDate: function(date, day) {
		let dd = new Date(date)
		dd.setDate(dd.getDate() + day)
		let y = dd.getFullYear()
		let m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1
		let d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate()
		return y + '-' + m + '-' + d
	},
	/**
	 * @description: 指定日期前/后几天
	 * @param {*} num 指定多少分钟后
	 * @return {string}
	 */
	getNextMin: function(num) {
		let date=new Date();     //1. js获取当前时间
		let min=date.getMinutes();  //2. 获取当前分钟
		date.setMinutes(min+num);  //3. 设置当前时间+10分钟：把当前分钟数+10后的值重新设置为date对象的分钟数
		let y = date.getFullYear()
		let m = (date.getMonth() + 1) < 10 ? ("0" + (date.getMonth() + 1)) : (date.getMonth() + 1);
		let d = date.getDate() < 10 ? ("0" + date.getDate()) : date.getDate();
		let h = date.getHours() < 10 ? ('0' + date.getHours()) : date.getHours()
		let f = date.getMinutes() < 10 ? ('0' + date.getMinutes()) : date.getMinutes()
		return y+'-'+m+'-'+d + " " + h + ":" + f
	},
	/**
	 * @description: 当前日期是否在指定日期内 不传时分秒只能当天小于结束日期，
	 * 不包含结束日期但是包含开始日期，不穿都是00，但是开始时间000代表着开始时间，结束00代表结束日期结束
	 * @param {*} startTime 开始日期 YYYY-MM-DD HH:ii:ss
	 * @param {*} endTime 结束日期 YYYY-MM-DD HH:ii:ss
	 * @return {fn} success 回调函数
	 */
	getIsTimeIn: function(startTime, endTime, success) {
		let nowStamp = this.now() //当前时间 时间戳
		let startStamp = new Date(startTime).getTime() //开始时间 时间戳
		let endStamp = new Date(endTime).getTime() //结束时间 时间戳
		console.log(start);
		console.log(new Date().getTime());
		// return success()
		if (startStamp && !endStamp) { //只传了开始时间，那么大于开始时间一般是可执行。反之不可
			let flag = nowStamp >= startStamp ? true : false
			success(flag)
		}
		if (!startStamp && endStamp) { //只传了结束时间，那么小于于开始时间一般是可执行。反之不可
			let flag = nowStamp <= endStamp ? true : false
			success(flag)
		}
		if (startStamp && endStamp) { //全传，那么d大于开始时间小于结束时间一般是可执行。反之不可
			let flag = nowStamp >= startStamp && nowStamp <= endStamp ? true : false
			success(flag)
		}
	},
	/**
	 * @description: 人性化时间格式
	 * @param {*} shortTime 传入时间 YYYY-MM-DD HH:ii:ss
	 * @return {*} 返回时间
	 */
	getTimeShort: function(shortTime) {
		shortTime = this.toTimeStamp(shortTime)
		let nowStamp = this.now();
		let chaStamp = (nowStamp - shortTime) / 1000; //时间戳相减得到毫秒，毫秒除以1000得到秒
		let format = this.toDate(shortTime, 'array').map(Number)
		let desc = format[3] > 12 ? '下午' : '上午'
		console.log(format);
		console.log(chaStamp);
		if (chaStamp < 86400) { //86400秒等于一天
			// 当天
			return `${desc} ${format[3]}:${format[4]}`;
		} else if (chaStamp < 518400) {
			// 隔天 显示日期+时间
			return `${format[1]}月${format[2]}日 ${format[3]}:${format[4]}`;
		} else {
			// 隔年 显示完整日期+时间
			return `${format[0]}年${format[1]}月${format[2]}日 ${format[3]}:${format[4]}`;
		}
	},
	/**
	 * @description: 计算当前日期星座
	 * @param {*} shortTime 传入时间 YYYY-MM-DD HH:ii:ss
	 * @return {*} 返回时间
	 */
	getHoroscope: function(date) {
		let c = ['摩羯', '水瓶', '双鱼', '白羊', '金牛', '双子', '巨蟹', '狮子', '处女', '天秤', '天蝎', '射手', '摩羯']
		date = new Date(date);
		let month = date.getMonth() + 1;
		let day = date.getDate();
		let startMonth = month - (day - 14 < '865778999988'.charAt(month));
		return c[startMonth] + '座';
	},
	/**  
	 * @description 获取ref ( 循环获取，直到 组件创建完成并获取成功 )
	 * @param {string} ref  名称
	 * @param {string} _this  this 为了保持 this 作用域
	 * @param {string} count  0 起始次数
	 * @returns {fun} 回调函数，当成功获取到 ref 时执行，传递 ref 数据
	 */
	getRefs: function(ref, _this, count, fun) {
		if (count >= 40) {
			return null;
		}
		let refReturn = _this.$refs[ref];
		if (refReturn) {
			fun(refReturn);
			return;
		} else {
			count++;
			setTimeout(() => {
				this.getRefs(ref, _this, count, fun);
			}, 100);
		}
	},
	/**
	 * @description: 金额中文大写
	 * @param {*} price
	 * @return {*}
	 */
	chineseDigital: function(price) {
		if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(price)) return '数据非法'
		let unit = '千百拾亿千百拾万千百拾元角分'
		let str = ''
		parseFloat(price) < 0 && (str = '负')
		price += '00'
		let p = price.indexOf('.')
		if (p >= 0) price = price.substring(0, p) + price.substr(p + 1, 2)
		unit = unit.substr(unit.length - n.length)
		for (let i = 0; i < price.length; i++) str += '零壹贰叁肆伍陆柒捌玖'.charAt(price.charAt(i)) + unit.charAt(i)
		return str
			.replace(/零(千|百|拾|角)/g, '零')
			.replace(/(零)+/g, '零')
			.replace(/零(万|亿|元)/g, '$1')
			.replace(/(亿)万|壹(拾)/g, '$1$2')
			.replace(/^元零?|零分/g, '')
			.replace(/元$/g, '元整')
	},
	/**
	 * @description: 加法运算
	 * @param {*} arg1
	 * @param {*} arg2
	 * @return {*}
	 */
	operationAdd: function(arg1, arg2) {
		let r1, r2, m, c
		try {
			r1 = arg1.toString().split('.')[1].length
		} catch (e) {
			r1 = 0
		}
		try {
			r2 = arg2.toString().split('.')[1].length
		} catch (e) {
			r2 = 0
		}
		c = Math.abs(r1 - r2)
		m = Math.pow(10, Math.max(r1, r2))
		if (c > 0) {
			let cm = Math.pow(10, c)
			if (r1 > r2) {
				arg1 = Number(arg1.toString().replace('.', ''))
				arg2 = Number(arg2.toString().replace('.', '')) * cm
			} else {
				arg1 = Number(arg1.toString().replace('.', '')) * cm
				arg2 = Number(arg2.toString().replace('.', ''))
			}
		} else {
			arg1 = Number(arg1.toString().replace('.', ''))
			arg2 = Number(arg2.toString().replace('.', ''))
		}
		return (arg1 + arg2) / m
	},
	/**
	 * @description: 减法运算
	 * @param {*} arg1
	 * @param {*} arg2
	 * @return {*}
	 */
	operationSub: function(arg1, arg2) {
		let r1, r2, m, n
		try {
			r1 = arg1.toString().split('.')[1].length
		} catch (e) {
			r1 = 0
		}
		try {
			r2 = arg2.toString().split('.')[1].length
		} catch (e) {
			r2 = 0
		}
		m = Math.pow(10, Math.max(r1, r2)) //last modify by deeka //动态控制精度长度
		n = r1 >= r2 ? r1 : r2
		return ((arg1 * m - arg2 * m) / m).toFixed(n)
	},
	/**
	 * @description: 乘法运算
	 * @param {*} arg1
	 * @param {*} arg2
	 * @return {*}
	 */
	operationMul: function(arg1, arg2) {
		let m = 0,
			s1 = arg1.toString(),
			s2 = arg2.toString()
		try {
			m += s1.split('.')[1].length
		} catch (e) {}
		try {
			m += s2.split('.')[1].length
		} catch (e) {}
		return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m)
	},
	/**
	 * @description: 除法运算
	 * @param {*} arg1
	 * @param {*} arg2
	 * @return {*}
	 */
	operationDiv: function(arg1, arg2) {
		let t1 = 0,
			t2 = 0,
			r1,
			r2
		try {
			t1 = arg1.toString().split('.')[1].length
		} catch (e) {}
		try {
			t2 = arg2.toString().split('.')[1].length
		} catch (e) {}
		r1 = Number(arg1.toString().replace('.', ''))
		r2 = Number(arg2.toString().replace('.', ''))
		return (r1 / r2) * Math.pow(10, t2 - t1)
	},
	/**
	 * @description: 防抖
	 * @param {time} wait是指等待时长，在wait时间内多次触发函数只会被执行一次
	 * @param {time} immediate是否立即执行，true表示wait秒内触发只会执行第一次触发；false表示wait秒内触发只会执行最后一次触发
	 * @return {*} fn是事件触发执行的函数
	 */
	debounce: function(func, wait = 500, immediate = false) {
		// 清除定时器
		if (timeoutFdJl !== null) clearTimeout(timeoutFdJl);
		// 立即执行，传true 则不进行防抖 一般不传递第三个参数
		if (immediate) {
			var callNow = !timeoutFdJl;
			timeoutFdJl = setTimeout(function() {
				timeoutFdJl = null;
			}, wait);
			if (callNow) typeof func === 'function' && func();
		} else {
			// 设置定时器，当最后一次操作后，timeout不会再被清除，所以在延时wait毫秒后执行func回调方法
			timeoutFdJl = setTimeout(function() {
				typeof func === 'function' && func();
			}, wait);
		}
	},
	throttle: function(fn, wait = 500, isImmediate = false) { //有问题
		let flag = true;
		if (isImmediate) {
			return function() {
				if (flag) {
					fn.apply(this, arguments);
					flag = false;
					setTimeout(() => {
						flag = true
					}, wait)
				}
			}
		}
		return function() {
			if (flag == true) {
				flag = false
				setTimeout(() => {
					fn.apply(this, arguments)
					flag = true
				}, wait)
			}
		}
	}


}
